package com.pj.xfxh.listener;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.pj.xfxh.constants.Constant;
import com.pj.xfxh.domain.JsonParse;
import com.pj.xfxh.domain.RoleContent;
import com.pj.xfxh.domain.Text;
import com.pj.xfxh.thread.MyThread;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;

import java.io.IOException;
import java.util.List;
import java.util.UUID;

@Slf4j
public class XhWebSocketListener extends WebSocketListener {
    public static final Gson gson = new Gson();
    public StringBuilder totalAnswer; // 大模型的答案汇总
    public Boolean answerFinished = false; // 大模型的答案汇总
    public List<RoleContent> historyList; // 对话历史存储集合
    private String userId;// 个性化参数
    private Boolean wsCloseFlag;
    private String question;
    private WebSocket webSocket;

    public XhWebSocketListener(List<RoleContent> historyList){

        this.historyList = historyList;
    }

    @Override
    public void onOpen(WebSocket webSocket, Response response) {
        super.onOpen(webSocket, response);
        this.webSocket = webSocket;
    }

    @Override
    public void onMessage(WebSocket webSocket, String text) {
        JsonParse myJsonParse = gson.fromJson(text, JsonParse.class);
        if (myJsonParse.getHeader().getCode() != 0) {
            log.error("发生错误，错误码为:{}\n本次请求的sid为：{}", myJsonParse.getHeader().getCode(), myJsonParse.getHeader().getSid());
            webSocket.close(1000, "");
        }
        List<Text> textList = myJsonParse.getPayload().getChoices().getText();
        for (Text temp : textList) {
            totalAnswer.append(temp.getContent());
        }
        if (myJsonParse.getHeader().getStatus() == 2) {
            // 可以关闭连接，释放资源
            if (canAddHistory()) {
                RoleContent roleContent = new RoleContent();
                roleContent.setRole("assistant");
                roleContent.setContent(totalAnswer.toString());
                historyList.add(roleContent);
            } else {
                historyList.remove(0);
                RoleContent roleContent = new RoleContent();
                roleContent.setRole("assistant");
                roleContent.setContent(totalAnswer.toString());
                historyList.add(roleContent);
            }
            wsCloseFlag = true;
            answerFinished = true;
        }
    }

    @Override
    public void onFailure(WebSocket webSocket, Throwable t, Response response) {
        super.onFailure(webSocket, t, response);
        try {
            if (null != response) {
                int code = response.code();
                log.error("onFailure code:{}\nonFailure body:{}", response.code(), response.body().string());
                if (101 != code) {
                    log.error("connection failed");
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public boolean canAddHistory() {  // 由于历史记录最大上线1.2W左右，需要判断是能能加入历史
        int history_length = 0;
        for (RoleContent temp : historyList) {
            history_length = history_length + temp.getContent().length();
        }
        if (history_length > 12000) {
            historyList.remove(0);
            historyList.remove(1);
            historyList.remove(2);
            historyList.remove(3);
            historyList.remove(4);
            return false;
        } else {
            return true;
        }
    }

    public String getAnswer() throws InterruptedException {
        while (true) {
            Thread.sleep(200);
            if (answerFinished) {
                break;
            }
        }
        answerFinished = false;
        String answer = totalAnswer.toString();
        log.info("answer:{}", answer);
        return answer;
    }

    /**
     * 请求参数
     *
     * @return
     */
    private String getRequestJson() {
        JSONObject header = new JSONObject();  // header参数
        header.put("app_id", Constant.appid);
        header.put("uid", UUID.randomUUID().toString().substring(0, 10));
        JSONObject parameter = new JSONObject(); // parameter参数
        JSONObject chat = new JSONObject();
        chat.put("domain", Constant.domain);
        chat.put("temperature", Constant.temperature);
        chat.put("max_tokens", Constant.maxTokens);
        parameter.put("chat", chat);
        JSONObject payload = new JSONObject(); // payload参数
        JSONObject message = new JSONObject();
        JSONArray text = new JSONArray();
        // 历史问题获取
        if (historyList.size() > 0) {
            for (RoleContent tempRoleContent : historyList) {
                text.add(JSON.toJSON(tempRoleContent));
            }
        }
        //你作为一位饱读诗书的取名专家，用四字成语给出‘心’这个名字的寓意
        //你作为一位饱读诗书的取名专家，给出‘心语’这个名字的寓意
        // ‘力’字，你作为一位饱读诗书的取名专家，概括这个字作为名字的寓意，并用褒义的成语概括，给出成语解释。回答格式：{  "symbolism": "",  "idiom": "",  "explanation": ""}
        RoleContent roleContent = new RoleContent();
        roleContent.setRole("user");
        roleContent.setContent(question);
        text.add(JSON.toJSON(roleContent));
        historyList.add(roleContent);
        message.put("text", text);
        payload.put("message", message);
        JSONObject requestJson = new JSONObject();
        requestJson.put("header", header);
        requestJson.put("parameter", parameter);
        requestJson.put("payload", payload);
        return requestJson.toString();
    }

    public void setQuestion(String question, Boolean wsCloseFlag) throws InterruptedException {
        totalAnswer = new StringBuilder();
        this.wsCloseFlag = wsCloseFlag;
        this.question = question;
        while (true) {
            Thread.sleep(200);
            if (webSocket != null) {
                break;
            }
        }
        new MyThread(webSocket, getRequestJson(), this.wsCloseFlag).start();
    }
}
